<?php
	/**
	 * 
	 * Redistribution and use in source and binary forms, with or without
	 * modification, are permitted provided that the following conditions are met:
	 *
	 *     * Redistributions of source code must retain the above copyright
	 *       notice, this list of conditions and the following disclaimer.
	 *     * Redistributions in binary form must reproduce the above copyright
	 *       notice, this list of conditions and the following disclaimer in the
	 *       documentation and/or other materials provided with the distribution.
	 *     * Neither the name of the University of California, Berkeley nor the
	 *       names of its contributors may be used to endorse or promote products
	 *       derived from this software without specific prior written permission.
	 *
	 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
	 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
	 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
	 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
	 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
	 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
	 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
	 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
	 * 
	 * 
	 * Classe de interface do pSQLite
	 * @author Bruno Pitteli Gonçalves <scorninpc<at>gmail<dot>com>
	 * @author Carlos Henrrique Marques <rickadt<at>gmail<dot>com>
	 * @version Revision 2
	 * @license BSD license
	 *
	 *	Change log
	 *	Revision 2:
	 *		Class initialize methods
	 */
	
	class pSQLite_Interface
	{
		/**
		 * Array of widgets
		 * @since Revision 2
		 * @name $widgets
		 * @access public
		 */
		public $widgets = array();

		/**
		 * Accelerators (shotcuts)
		 * @since Revision 2
		 * @name $accelerator
		 * @access public
		 */
		public $accelerator;
		
		/**
		 * Class contructor
		 * @since Revision 2
		 * @name __construct
		 * @access public
		 */
		public function __construct()
		{
			// Create a window
			$this->widgets['frmMain']	= new GtkWindow();
			$this->widgets['frmMain']->set_title("pSQLite :: Sem banco de dados.");
			
			$this->widgets['frmMain']->maximize();

			// Box 1
			$this->widgets['vbox1'] = new GtkVBox(FALSE, 4);

			// ---------------------------------------------------------
			// Create menu bar (Pack 1)
			$this->widgets['mnuBar']['object'] = new GtkMenuBar();
			
				// Files
				$mnuTemp = new GtkMenuItem('Arquivos');
				$this->widgets['mnuBar']['object']->append($mnuTemp);
				$this->widgets['mnuBar']['files']['object'] = $mnuTemp;

					$menu = new GtkMenu();

					// Open Database
					$this->widgets['mnuBar']['files']['opendatabase'] = new GtkImageMenuItem('Abrir banco de dados');
					$this->widgets['mnuBar']['files']['opendatabase']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_OPEN,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['opendatabase']);

					// Open Recent Database
					$this->widgets['mnuBar']['files']['openrecent'] = new GtkMenuItem('Banco de dados recentes');
					$menu->append($this->widgets['mnuBar']['files']['openrecent']);

					// Separator
					$menu->append(new GtkSeparatorMenuItem());

					// New tab query
					$this->widgets['mnuBar']['files']['newtab'] = new GtkImageMenuItem('Nova aba');
					$this->widgets['mnuBar']['files']['newtab']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_NEW,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['newtab']);
					$this->widgets['mnuBar']['files']['newtab']->set_sensitive(FALSE);

					// New tab edit query
					$this->widgets['mnuBar']['files']['editquery'] = new GtkImageMenuItem('Editar tabela');
					$this->widgets['mnuBar']['files']['editquery']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_EDIT,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['editquery']);
					$this->widgets['mnuBar']['files']['editquery']->set_sensitive(FALSE);
					
					// Open query
					$this->widgets['mnuBar']['files']['openquery'] = new GtkImageMenuItem('Abrir query');
					$this->widgets['mnuBar']['files']['openquery']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_OPEN,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['openquery']);
					$this->widgets['mnuBar']['files']['openquery']->set_sensitive(FALSE);

					// Separator
					$menu->append(new GtkSeparatorMenuItem());
					
					// Save query
					$this->widgets['mnuBar']['files']['savequery'] = new GtkImageMenuItem('Salvar query');
					$this->widgets['mnuBar']['files']['savequery']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_SAVE,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['savequery']);
					$this->widgets['mnuBar']['files']['savequery']->set_sensitive(FALSE);
					
					// Save query as
					$this->widgets['mnuBar']['files']['savequeryas'] = new GtkImageMenuItem('Salvar query como ...');
					$this->widgets['mnuBar']['files']['savequeryas']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_SAVE_AS,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['savequeryas']);
					$this->widgets['mnuBar']['files']['savequeryas']->set_sensitive(FALSE);

					// Export result
					$this->widgets['mnuBar']['files']['export'] = new GtkMenuItem('Exportar');
					$menu->append($this->widgets['mnuBar']['files']['export']);
					$this->widgets['mnuBar']['files']['export']->set_sensitive(FALSE);

					// Close tab
					$this->widgets['mnuBar']['files']['closetab'] = new GtkImageMenuItem('Fechar aba');
					$this->widgets['mnuBar']['files']['closetab']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_CLOSE,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['closetab']);
					$this->widgets['mnuBar']['files']['closetab']->set_sensitive(FALSE);

					// Separator
					$menu->append(new GtkSeparatorMenuItem());

					// Close tab
					$this->widgets['mnuBar']['files']['exit'] = new GtkImageMenuItem('Sair');
					$this->widgets['mnuBar']['files']['exit']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_QUIT,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['files']['exit']);
					
					$this->widgets['mnuBar']['files']['object']->set_submenu($menu);

				// Script
				$mnuTemp = new GtkMenuItem('Script');
				$this->widgets['mnuBar']['object']->append($mnuTemp);
				$this->widgets['mnuBar']['script']['object'] = $mnuTemp;

					$menu = new GtkMenu();

					// Execute
					$this->widgets['mnuBar']['script']['execute'] = new GtkImageMenuItem('Executar');
					$this->widgets['mnuBar']['script']['execute']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_EXECUTE,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['script']['execute']);
					$this->widgets['mnuBar']['script']['execute']->set_sensitive(FALSE);
					
					// Stop
					$this->widgets['mnuBar']['script']['stop'] = new GtkImageMenuItem('Parar');
					$this->widgets['mnuBar']['script']['stop']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_STOP,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['script']['stop']);
					$this->widgets['mnuBar']['script']['stop']->set_sensitive(FALSE);

					// Separator
					$menu->append(new GtkSeparatorMenuItem());

					// Apply
					$this->widgets['mnuBar']['script']['apply'] = new GtkImageMenuItem('Aplicar');
					$this->widgets['mnuBar']['script']['apply']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_APPLY,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['script']['apply']);
					$this->widgets['mnuBar']['script']['apply']->set_sensitive(FALSE);
					
					// Cancel
					$this->widgets['mnuBar']['script']['cancel'] = new GtkImageMenuItem('Cancelar');
					$this->widgets['mnuBar']['script']['cancel']->set_image(
						GtkImage::new_from_stock(
							Gtk::STOCK_CANCEL,
							Gtk::ICON_SIZE_MENU
						)
					);
					$menu->append($this->widgets['mnuBar']['script']['cancel']);
					$this->widgets['mnuBar']['script']['cancel']->set_sensitive(FALSE);
					
				$this->widgets['mnuBar']['script']['object']->set_submenu($menu);

			// Pack widget
			$this->widgets['vbox1']->pack_start($this->widgets['mnuBar']['object'], FALSE);

			// ---------------------------------------------------------
			// Shotcuts
			$this->accelerator = new GtkAccelGroup();
			$this->widgets['frmMain']->add_accel_group($this->accelerator);
			$this->widgets['mnuBar']['files']['newtab']->add_accelerator(
				"activate",
				$this->accelerator,
				ord("T"),
				Gdk::CONTROL_MASK,
				1
			);
			$this->widgets['mnuBar']['files']['closetab']->add_accelerator(
				"activate",
				$this->accelerator,
				ord("W"),
				Gdk::CONTROL_MASK,
				1
			);
			$this->widgets['mnuBar']['files']['opendatabase']->add_accelerator(
				"activate",
				$this->accelerator,
				ord("O"),
				Gdk::CONTROL_MASK,
				1
			);
			$this->widgets['mnuBar']['script']['execute']->add_accelerator(
				"activate",
				$this->accelerator,
				Gdk::KEY_F5,
				0,
				1
			);
			// ---------------------------------------------------------
			// Create tool bar (Pack 2)
			$this->widgets['tolBar']['object'] = new GtkToolBar();
			$this->widgets['tolBar']['object']->set_show_arrow(TRUE);
			$this->widgets['tolBar']['object']->set_toolbar_style(Gtk::TOOLBAR_ICONS);
				
				// Open
				$this->widgets['tolBar']['open'] = GtkMenuToolButton::new_from_stock(Gtk::STOCK_OPEN);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['open'], -1);
				
				// Separator
				$this->widgets['tolBar']['object']->insert(new GtkSeparatorToolItem(), -1);

				// New
				$this->widgets['tolBar']['new'] = GtkToolButton::new_from_stock(Gtk::STOCK_NEW);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['new'], -1);
				$this->widgets['tolBar']['new']->set_sensitive(FALSE);

				// Close
				$this->widgets['tolBar']['close'] = GtkToolButton::new_from_stock(Gtk::STOCK_CLOSE);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['close'], -1);
				$this->widgets['tolBar']['close']->set_sensitive(FALSE);
				
				// Execute
				$this->widgets['tolBar']['execute'] = GtkToolButton::new_from_stock(Gtk::STOCK_EXECUTE);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['execute'], -1);
				$this->widgets['tolBar']['execute']->set_sensitive(FALSE);
				
				// Stop
				$this->widgets['tolBar']['stop'] = GtkToolButton::new_from_stock(Gtk::STOCK_STOP);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['stop'], -1);
				$this->widgets['tolBar']['stop']->set_sensitive(FALSE);

				// Separator
				$this->widgets['tolBar']['object']->insert(new GtkSeparatorToolItem(), -1);
				
				// Edit
				$this->widgets['tolBar']['edit'] = GtkToolButton::new_from_stock(Gtk::STOCK_EDIT);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['edit'], -1);
				$this->widgets['tolBar']['edit']->set_sensitive(FALSE);
				
				// Apply
				$this->widgets['tolBar']['apply'] = GtkToolButton::new_from_stock(Gtk::STOCK_APPLY);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['apply'], -1);
				$this->widgets['tolBar']['apply']->set_sensitive(FALSE);

				// Cancel
				$this->widgets['tolBar']['cancel'] = GtkToolButton::new_from_stock(Gtk::STOCK_NO);
				$this->widgets['tolBar']['object']->insert($this->widgets['tolBar']['cancel'], -1);
				$this->widgets['tolBar']['cancel']->set_sensitive(FALSE);

				// Separator
				$this->widgets['tolBar']['object']->insert(new GtkSeparatorToolItem(), -1);
				
			// Pack widget
			$this->widgets['vbox1']->pack_start($this->widgets['tolBar']['object'], FALSE);

			// Create Paned 1 (Pack 3)
			$this->widgets['paned1'] = new GtkHPaned();
			$this->widgets['paned1']->set_border_width(0);
			
			// Create notebook (Pack Left)
			$this->widgets['ntbQueries'] = new GtkNotebook();
			$this->widgets['ntbQueries']->set_scrollable(TRUE);
			$this->widgets['paned1']->pack1($this->widgets['ntbQueries'], TRUE);
			
			// Add paned in box 3
			$this->widgets['vbox1']->pack_start($this->widgets['paned1'], TRUE);

			// Create a treevew (Pack Right)
			$this->widgets['trvStruct'] = $this->createTreeView(array('Tabelas'), FALSE);
			$scrolled = new GtkScrolledWindow();
			$scrolled->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
			$scrolled->add_with_viewport($this->widgets['trvStruct']);
			$scrolled->set_size_request(200, FALSE);
			$this->widgets['paned1']->pack2($scrolled, FAlSE);

			// Create a status bar (box 4)
			$this->widgets['stsBar'] = new GtkProStatusbar();

			// ProgressBar
			$this->widgets['pgsBar'] = new GtkProgressBar();
			$this->widgets['pgsBar']->set_size_request(100, FALSE);

			$this->widgets['stsBar']->add($this->widgets['pgsBar']);
			$this->widgets['vbox1']->pack_start($this->widgets['stsBar'], FALSE);
			
			// Connect widgets with signals
			$this->__widgetsConnect();
			
			// Add Package 1
			$this->widgets['frmMain']->add($this->widgets['vbox1']);
			
			// Show all widgets
			$this->widgets['frmMain']->show_all();
			
			// Load frmMain_onload
			$this->frmMain_onload();
		}

		/* Create a openRecentMenu
		 * @since Revision 9
		 * @name addRecentOpennedMenu
		 * @param $file - String
		 * @access public
		 */
		public function addRecentOpennedMenu($file){
			$item = new GtkMenuItem($file);
			$item->connect_simple("activate", array($this, "mnuRecents_onactivate"), $file);
			$this->widgets['mnuRecents']->append($item);
			$this->widgets['mnuRecents']->show_all();
		}

		/**
		 * Create a treeview
		 * @since Revision 2
		 * @name createTreeView
		 * @access public
		 * @param $columns - Array (Array of columns name)
		 * @param $colors - Bool (Flag to make zebra efect)
		 * @return Resource (an GtkTreeView object)
		 */
		public function createTreeView($columns, $colors=TRUE)
		{
			$types = array();
			for($i=0; $i<count($columns); $i++)
			{
				$types[] = TYPE_STRING;
			}
			$model = new GtkListStore();
			$model->set_column_types($types);
			$treeview = new GtkTreeView($model);
			for($i=0; $i<count($columns); $i++)
			{
				$render = new GtkCellRendererText();
				$column = new GtkTreeViewColumn($columns[$i], $render, 'text', $i);
				$column->set_resizable(TRUE);
				if($colors)
				{
					$column->set_cell_data_func($render, array($this, "trvColumnFormat"), $i);
				}
				$treeview->append_column($column);
			}
			return $treeview;
		}

		/**
		 * Format a cells of treeview
		 * @since Revision 2
		 * @name trvColumnFormat
		 * @access public
		 * @description Callback function to format cells
		 */
		public function trvColumnFormat($column, $cell, $model, $iter, $col_num)
		{
			$path = $model->get_path($iter);
    		$row_num = $path[0];

    		if(!empty($this->tabEdit[$this->currentTab]['linecolor'][$row_num]))
    		{
    			$color = $this->tabEdit[$this->currentTab]['linecolor'][$row_num];
			}
			else
			{
				if($row_num % 2 == 1)
				{
					$color = "#EEEEEE";
				}
				else
				{
					$color = "#FFFFFF";
				}
			}

			$cell->set_property("cell-background", $color);
		}
		
		/**
		 * Create a new tab in notebook
		 * @since Revision 2
		 * @name createQueryTab
		 * @access public
		 * @param $count - Tab number
		 * @return Integer (number of tab)
		 */
		public function createQueryTab($count)
		{
			$paned = new GtkVPaned();
			$paned->set_border_width(0);
			
			// Pack 1
			$scintilla = $this->createScintilla();
			$paned->add1($scintilla);

			// Pack 1
			$treeview = $this->createTreeView(array(''));

			// Create srolls
			$scrolled = new GtkScrolledWindow();
			$scrolled->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
			$scrolled->add_with_viewport($treeview);
			$paned->add2($scrolled);
			
			// Add new tab
			$insertedIndex = $this->widgets['ntbQueries']->insert_page(
				$paned,
				new GtkLabel('Recordset ' . $count),
				$count + 1
			);

			$this->widgets['ntbQueries']->show_all();
			return $insertedIndex;
		}

		/**
		 * Create a new scintilla
		 * @since Revision 2
		 * @name createScintilla
		 * @access public
		 * @return Resource (GtkScintilla object)
		 */
		public function createScintilla()
		{
			// Create a textview in left top
			$scintilla = new GtkScintilla();
			
			// Identation
			$scintilla->set_indentation_guides(1);
			$scintilla->set_use_tabs(1);
			$scintilla->set_indent(4);
			$scintilla->set_tab_width(4);
			
			// Wrapper line
			$scintilla->set_wrap_mode(2);
			
			// Line numbers bar
			$scintilla->style_set_font(SCINTILLA_STYLE_DEFAULT, SCINTILLA_STYLE_FONT);
			$scintilla->style_set_fore(SCINTILLA_STYLE_LINE_NUMBER, 0xFFFFFF); // BGR
			$scintilla->style_set_back(SCINTILLA_STYLE_LINE_NUMBER, 0xC56A31); // BGR
			$scintilla->set_margin_width_n(0, 23);
			
			// Change actual line color
			$scintilla->set_caret_line_visible(1);
			$scintilla->set_caret_line_back(0xf8f1ef); // BGR
			$scintilla->set_size_request(FALSE, 100);
			
			// Highlight
			$scintilla->style_set_fore(SCINTILLA_SQL_COMMENT_LINE, 0x0099ff);
			$scintilla->style_set_fore(SCINTILLA_SQL_COMMENT_BLOCK, 0x0099ff);
			$scintilla->style_set_fore(SCINTILLA_SQL_NUMBER, 0x0000FF);
			$scintilla->style_set_fore(SCINTILLA_SQL_SINGLE_STRING, 0x0000CC);
			$scintilla->style_set_fore(SCINTILLA_SQL_DOUBLE_STRING, 0x0000CC);
			$scintilla->style_set_fore(SCINTILLA_SQL_KEYWORD, 0xFF0000);
			$scintilla->style_set_fore(SCINTILLA_SQL_OPERATOR, 0x990000);
			
			return $scintilla;
		}
		
		/**
		 * Connect all widget
		 * @since Revision 2
		 * @name __widgetsConnect
		 * @access private
		 */
		private function __widgetsConnect()
		{
			$this->widgets['frmMain']->connect("delete-event", array($this, "frmMain_unload"));

			$this->widgets['tolBar']['open']->connect_simple("clicked", array($this, "tolBar_onclick"), "open");
			$this->widgets['tolBar']['new']->connect_simple("clicked", array($this, "tolBar_onclick"), "new");
			$this->widgets['tolBar']['close']->connect_simple("clicked", array($this, "tolBar_onclick"), "close");
			$this->widgets['tolBar']['execute']->connect_simple("clicked", array($this, "tolBar_onclick"), "execute");
			$this->widgets['tolBar']['stop']->connect_simple("clicked", array($this, "tolBar_onclick"), "stop");
			$this->widgets['tolBar']['edit']->connect_simple("clicked", array($this, "tolBar_onclick"), "edit");
			$this->widgets['tolBar']['apply']->connect_simple("clicked", array($this, "tolBar_onclick"), "apply");
			$this->widgets['tolBar']['cancel']->connect_simple("clicked", array($this, "tolBar_onclick"), "cancel");

			$this->widgets['ntbQueries']->connect("switch-page", array($this, "ntbQueries_onchange"));

			$this->widgets['trvStruct']->connect("button_press_event", array($this, "trvStruct_buttonpress"));

			$this->widgets['mnuBar']['files']['opendatabase']->connect_simple("activate", array($this, "tolBar_onclick"), "open");
			$this->widgets['mnuBar']['files']['newtab']->connect_simple("activate", array($this, "tolBar_onclick"), "new");
			$this->widgets['mnuBar']['files']['closetab']->connect_simple("activate", array($this, "tolBar_onclick"), "close");
			$this->widgets['mnuBar']['script']['execute']->connect_simple("activate", array($this, "tolBar_onclick"), "execute");
			$this->widgets['mnuBar']['script']['stop']->connect_simple("activate", array($this, "tolBar_onclick"), "stop");
			$this->widgets['mnuBar']['files']['editquery']->connect_simple("activate", array($this, "tolBar_onclick"), "edit");
			$this->widgets['mnuBar']['script']['apply']->connect_simple("activate", array($this, "tolBar_onclick"), "apply");
			$this->widgets['mnuBar']['script']['cancel']->connect_simple("activate", array($this, "tolBar_onclick"), "cancel");
			$this->widgets['mnuBar']['files']['exit']->connect_simple("activate", array($this, "frmMain_unload"));
		}

	} // class pSQLite_Interface
